package com.jingtai.platform.advice;

import com.jingtai.common.template.ResultMapInfo;
import com.jingtai.common.webfacade.error.CommonException;
import com.jingtai.core.template.BaseController;
import com.jingtai.validate.asserts.CAssertIllegalArgumentException;
import com.jingtai.validate.bean.DataVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import org.thymeleaf.exceptions.TemplateInputException;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.io.FileNotFoundException;
import java.util.Map;
import java.util.Set;

/**
 * Description:
 * Create DateTime: 2020-04-17 19:20
 *
 * @author houyi
 */
@Slf4j
/*@RestControllerAdvice*/
public class GlobalDefaultExceptionHandler extends BaseController {

    /**
     * 拦截自定义错误信息
     *
     * @param exception CommonException
     * @return 错误信息
     */
    @ExceptionHandler(value = CommonException.class)
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> handlerNoHandlerFoundException(CommonException exception) {
        return returnResultMap(ResultMapInfo.OPERATE_FAIL, exception.getMessage());
    }

    /**
     * 拦截自定义错误信息
     * @param exception
     * @return
     */
    @ExceptionHandler(value = FileNotFoundException.class)
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> handlerNoHandlerFoundException(FileNotFoundException exception) {
        return returnResultMap(ResultMapInfo.OPERATE_FAIL, exception.getMessage());
    }

    /**
     * 拦截自定义错误信息
     * @param exception
     * @return
     */
    @ExceptionHandler(value = TemplateInputException.class)
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> handlerNoHandlerFoundException(TemplateInputException exception) {
        return returnResultMap(ResultMapInfo.OPERATE_FAIL, exception.getMessage());
    }

    /**
     * 拦截NoHandlerFoundException
     *
     * @param exception NoHandlerFoundException
     * @return 错误信息
     */
    @ExceptionHandler(value = NoHandlerFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Map<String, Object> handlerNoHandlerFoundException(NoHandlerFoundException exception) {
        return returnResultMap(ResultMapInfo.NOTFOUND, exception.getMessage());
    }

    /**
     * 拦截HttpRequestMethodNotSupportedException
     *
     * @param exception HttpRequestMethodNotSupportedException
     * @return 错误信息
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    public Map<String, Object> handlerHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException exception) {
        return returnResultMap(ResultMapInfo.ADDFAIL, exception.getMessage());
    }

    /**
     * 拦截Exception
     *
     * @param exception Exception
     * @return 错误信息
     */
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.OK)
    public Map<String, Object> handlerException(Exception exception) {
        return returnResultMap(ResultMapInfo.UNKNOW, exception.getMessage());
    }


    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    public ResponseEntity<DataVo<String>> MethodArgumentNotValidHandler(HttpServletRequest request,
                                                                        MethodArgumentNotValidException exception) throws Exception {
        log.debug("MethodArgumentNotValidHandler{}", exception);
        for (FieldError error : exception.getBindingResult().getFieldErrors()) {
            System.out.println(error.getDefaultMessage());
            System.out.println(error.getField());
            System.out.println(error.getRejectedValue());
            System.out.println(error);
            return ResponseEntity.ok(new DataVo<String>(HttpStatus.NOT_ACCEPTABLE).message(error.getDefaultMessage()));
        }
        return ResponseEntity.ok(new DataVo<String>(HttpStatus.INTERNAL_SERVER_ERROR));
    }

    @ExceptionHandler(value = CAssertIllegalArgumentException.class)
    // @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<DataVo<String>> CestcAssertIllegalArgumentExceptionHandler(HttpServletRequest request,
                                                                                     CAssertIllegalArgumentException exception) throws Exception {
        log.debug("CestcAssertIllegalArgumentExceptionHandler{}", exception);
        String message = exception.toString();
        if(message != null) {
            message = message.replace("com.jingtai.validate.asserts.CAssertIllegalArgumentException:", "");
        }
        return ResponseEntity.ok(new DataVo<String>(HttpStatus.BAD_REQUEST).message(message));

    }

    @ExceptionHandler(value = { ConstraintViolationException.class })
    // @ResponseBody
    public ResponseEntity<DataVo<String>> handleResourceNotFoundException(ConstraintViolationException e) {
        log.debug("ConstraintViolationException{}", e);
        Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
        for (ConstraintViolation<?> violation : violations) {
            return ResponseEntity.ok(new DataVo<String>(HttpStatus.BAD_REQUEST).message(violation.getMessage()));
        }
        return ResponseEntity.ok(new DataVo<String>(HttpStatus.INTERNAL_SERVER_ERROR));
    }

}
